package generator.web;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import generator.properties.MyBatisPlusGeneratorProperties;
import generator.util.ZipFileUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequestMapping
@RestController
public class CodeController {
	@Autowired
	private MyBatisPlusGeneratorProperties myBatisPlusGeneratorProperties;

	@GetMapping("code")
	public String getCode(HttpServletResponse response) {
		return code(myBatisPlusGeneratorProperties, response);
	}

	@PostMapping("code")
	public String postCode(MyBatisPlusGeneratorProperties generatorProperties, HttpServletResponse response) {
		return code(generatorProperties, response);
	}

	public String code(MyBatisPlusGeneratorProperties myBatisPlusGeneratorProperties, HttpServletResponse response) {
		String path = System.getProperty("user.dir") + File.separator + "generators";
		List<TableFill> tableFillList = new ArrayList<>();
		TableFill createField = new TableFill("create_time", FieldFill.INSERT);
		TableFill updateField = new TableFill("update_time", FieldFill.UPDATE);
		tableFillList.add(createField);
		tableFillList.add(updateField);

		AutoGenerator mpg = new AutoGenerator();

		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(path);// 需要生成的目录
		gc.setFileOverride(true);// 是否覆盖
		gc.setActiveRecord(true);
		gc.setEnableCache(false);// XML 二级缓存
		gc.setBaseResultMap(false);// XML ResultMap
		gc.setBaseColumnList(false);// XML columList
		gc.setMapperName("%sDAO");
		gc.setServiceName("%sService");
		gc.setAuthor("allnas");
		gc.setSwagger2(true);
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(myBatisPlusGeneratorProperties.getDbType());
		dsc.setDriverName(myBatisPlusGeneratorProperties.getDriverClassName());
		dsc.setUsername(myBatisPlusGeneratorProperties.getUsername());
		dsc.setPassword(myBatisPlusGeneratorProperties.getPassword());
		dsc.setUrl(myBatisPlusGeneratorProperties.getUrl());
		mpg.setDataSource(dsc);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
		strategy.setTablePrefix(myBatisPlusGeneratorProperties.getTablePrefix());
		strategy.setInclude(myBatisPlusGeneratorProperties.getIncludes());
		strategy.setEntityLombokModel(true);
		strategy.setLogicDeleteFieldName(myBatisPlusGeneratorProperties.getLogicDeleteFieldName());
		strategy.setTableFillList(tableFillList);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setParent(myBatisPlusGeneratorProperties.getParent());
		pc.setEntity(myBatisPlusGeneratorProperties.getEntity());
		pc.setMapper(myBatisPlusGeneratorProperties.getMapper());
		pc.setXml(myBatisPlusGeneratorProperties.getXml());
		pc.setController(myBatisPlusGeneratorProperties.getController());
		pc.setService(myBatisPlusGeneratorProperties.getService());
		pc.setServiceImpl(myBatisPlusGeneratorProperties.getServiceImpl());

		mpg.setPackageInfo(pc);

		// 执行生成
		mpg.execute();

		// 打包下载
		response.setContentType("APPLICATION/OCTET-STREAM");
		response.setHeader("Content-Disposition", "attachment; filename=file.zip");
		try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
			ZipFileUtils zip = ZipFileUtils.getInstance();
			File ff = new File(path);
			if (!ff.exists()) {
				ff.mkdirs();
			}
			zip.zip(ff, zos, "");
			zos.flush();
			
			TimeUnit.SECONDS.sleep(1L);
			FileUtils.deleteDirectory(new File(path));
		} catch (InterruptedException | IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}
}
